package game;


import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Random;

public class BallGame extends JFrame{
    private static final int WIDTH=800;//区域大小
    private static final int HEIGHT=800;//区域大小
    private static final int DELAY=1;//定时器延迟时间 单位为毫秒
    private Ball playerBall;
    private ArrayList <Ball> balls;
    private int score;
    private JLabel scoreLabel;//用来显示分数
    public BallGame(){
        setTitle("Ball Game");
        setSize(WIDTH, HEIGHT);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        //设置边框
        playerBall=new Ball(50,50,30,Color.blue);//初始小球
        balls=new ArrayList<>();
        score=0;

        addKeyListener(new KeyListener(){//用来监视键盘
            @Override
            public void keyTyped(KeyEvent e){
            }
            @Override
            public void keyPressed(KeyEvent e){
                handleKeyPress(e.getKeyCode());
            }
            @Override
            public void keyReleased(KeyEvent e){
            }
        });
        setFocusable(true);

        Timer timer=new Timer(DELAY,new ActionListener() {
            public void actionPerformed(ActionEvent e){
                updateBalls();//小球随意移动
                repaint();//绘制
                checkCollision();//监测碰撞
            }
        });
        timer.start();
        //分数的块
        scoreLabel = new JLabel("Score: 0");
        scoreLabel.setFont(new Font("Arial", Font.BOLD, 24));
        scoreLabel.setHorizontalAlignment(SwingConstants.RIGHT);
        scoreLabel.setVerticalAlignment(SwingConstants.TOP);
        scoreLabel.setBounds(WIDTH - 150, 20, 130, 30);
        add(scoreLabel);
    }
    private void handleKeyPress(int keyCode){//监测方向键 用来移动小球
        int step=10;
        switch(keyCode){
            case KeyEvent.VK_UP:
                playerBall.move(0, -step);
                break;
            case KeyEvent.VK_DOWN:
                playerBall.move(0, step);
                break;
            case KeyEvent.VK_LEFT:
                playerBall.move(-step, 0);
                break;
            case KeyEvent.VK_RIGHT:
                playerBall.move(step, 0);
                break;
        }
    }
    private void updateBalls(){//实时更新移动小球的位置
        if(isVisible()){
            for(Ball ball:balls){
                ball.x+=ball.disX;
                ball.y+=ball.disY;
                //如果超出范围 位移方向发生变化
                if(ball.x<=0||ball.x>=WIDTH-30){
                    ball.disX*=-1;
                }
                if(ball.y<=0||ball.y>=WIDTH-30){
                    ball.disY*=-1;
                }
            }
        }
    }
    public boolean contain(Ball a,Ball b){//判断a能不能吃掉b
        boolean flag=false;
        int dx=a.x-b.x,dy=a.y-b.y;
        double distance=Math.sqrt(dx*dx+dy*dy);
        int r1=a.r;
        if(distance<=r1) flag=true;
        return flag;
    }
    private void checkCollision(){
        int cnt=0;//用来计数现在比玩家的球小的球有几个 如果比较少就生成一号球 反之生成二号球
        for(int i=0;i<balls.size();i++){
            if(balls.get(i).r<=playerBall.r){
                cnt++;
            }
        }
        for(int i=0;i<balls.size();i++){
            Ball ball = balls.get(i);
            if(playerBall.intersects(ball)) {
                if(playerBall.r>=ball.r){
                    if(contain(playerBall,ball)){
                        playerBall.grow();
                        balls.remove(i);
                        i--;
                        if(cnt<3) spawnRandomBall1();
                        else spawnRandomBall2();
                        score+=ball.r;
                        scoreLabel.setText("Score: " + score);
                        if(score >=30000){
                            gameOver();
                        }
                    }
                }
                else{
                    if(contain(ball,playerBall)){
                        gameOver();
                    }
                }
            }
        }
    }
    private void spawnRandomBall1(){//生成一个比现在这个小的
        Random random=new Random();
        int x=random.nextInt(WIDTH-50);
        int y=random.nextInt(HEIGHT-50);
        int r=random.nextInt(playerBall.getR()-5)+5;
        Color color = new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
        Ball ball=new Ball(x,y,r,color);
        balls.add(ball);
    }
    private void spawnRandomBall2(){//随机生成一个
        Random random=new Random();
        int x=random.nextInt(WIDTH-50);
        int y=random.nextInt(HEIGHT-50);
        int r=random.nextInt(playerBall.getR()+50)+5;
        Color color = new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
        Ball ball=new Ball(x,y,r,color);
        balls.add(ball);
    }
    private void gameOver(){
        if(isVisible()) {//只有当 BallGame 窗口是可见的时候才显示消息框
            BoardDao boardDao=new BoardDaoImpl();
            boardDao.insertBoard(SignIn.playerId,score);
            JOptionPane.showMessageDialog(this, "游戏结束!");
        }
        dispose();
        //System.exit(0);
    }
    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;
        //玩家的球
        playerBall.draw(g2d);
        //其他小球
        for (Ball ball : balls) {
            ball.draw(g2d);
        }
    }
    public static void runGame(){
        SwingUtilities.invokeLater(() -> {
            BallGame ballGame = new BallGame();
            ballGame.setVisible(true);
            ballGame.spawnRandomBall1();
            ballGame.spawnRandomBall1();
            ballGame.spawnRandomBall2();
            ballGame.spawnRandomBall2();
            ballGame.spawnRandomBall2();
        });
    }
    private class Ball{
        private int x;//坐标
        private int y;//坐标
        private int r;//半径
        private int disX,disY;//位移
        private Color color;
        public Ball(int x,int y,int r,Color color){
            this.x=x;
            this.y=y;
            this.r=r;
            this.color=color;
            // this.disX=1;
            // this.disY=1;
            this.disX=(int)(Math.random()*3)+1;
            this.disY=(int)(Math.random()*3)+1;
        }
        public int getR(){
            return r;
        }
        public void draw(Graphics2D g2d){
            g2d.setColor(color);
            g2d.fillOval(x,y,2*r,2*r);
        }
        public void move(int dx,int dy){
            int tmpX=x+dx,tmpY=y+dy;
            if(tmpX>0&&tmpX<WIDTH-30){
                x+=dx;
            }
            if(tmpY>0&&tmpY<HEIGHT-30){
                y+=dy;
            }
        }
        public boolean intersects(Ball other){
            int dx=x-other.x,dy=y-other.y;
            double distance=Math.sqrt(dx*dx+dy*dy);
            return distance<=r+other.r;
        }
        public void grow(){
            r+=2;
        }
    }
    public static int max(int a,int b){
        int res=0;
        if(a>b) res=a;
        else res=b;
        return res;
    }
}
